﻿#include "TCPClient.h"
#include "../../Utils/netTools.h"
#include <string.h>

#ifdef __linux__
#include <arpa/inet.h>
#include <unistd.h>
#endif

namespace protocol {
	int32_t TCPClient::writeData(uint8_t* avBuf, uint32_t avBuflength)
	{
		return send(this->sock, reinterpret_cast<char*>(avBuf), avBuflength, 0);
	}

	int32_t TCPClient::readData(uint8_t* avBuf, uint32_t avBuflength)
	{
		return recv(this->sock, reinterpret_cast<char*>(avBuf), avBuflength, 0);
	}

	int TCPClient::connectToServer()
	{
		sock = socket(AF_INET, SOCK_STREAM, 0);
		struct sockaddr_in server_addr;
		memset(&server_addr, 0, sizeof(server_addr));
		server_addr.sin_family = AF_INET;
		server_addr.sin_port = htons(port);
		int ret = 0;
#ifdef _WIN32
		server_addr.sin_addr.s_addr = inet_addr(domain2IP(host).c_str());
#else
		ret = inet_aton(domain2IP(host).c_str(), &server_addr.sin_addr);
		if (ret == 0) {
			return errno;
		}
#endif
		ret = connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr));

		fd_set Write;
		FD_ZERO(&Write);
		FD_SET(sock, &Write);

#ifdef _WIN32
		TIMEVAL Timeout = { 0 };
		Timeout.tv_sec = connectTimeout_sec;
#else
		struct timeval Timeout;
		Timeout.tv_sec = connectTimeout_sec;  // 设置超时时间为 5 秒
		Timeout.tv_usec = 0;
#endif
		ret = select(sock + 1, NULL, &Write, NULL, &Timeout);

		 if (ret == 0)
		{
			return ERROR_TIMEOUT;
		}
		else if (ret != -1)
		{
			if (FD_ISSET(sock, &Write))
			{
				return 0;
			}
		}

#ifdef _WIN32
		return WSAGetLastError();
#else
		return errno;
#endif
	}

	void TCPClient::disConnect()
	{
		closesocket(sock);
	}

	TCPClient::TCPClient(const std::string avHost, const uint16_t avPort)
	{
		host = avHost;
		port = avPort;
	}

	void TCPClient::setConnectTimeout(uint8_t avsec)
	{
		connectTimeout_sec = avsec;
	}
}